#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/systick.h>
#include "non_blocking_led.h"

#include <stdio.h>

// 定义 LED 端口
#define LED_PORT GPIOA

// 定义 LED 引脚数组
const uint16_t led_pins[] = {GPIO5, GPIO6, GPIO7};
const uint8_t num_leds = sizeof(led_pins) / sizeof(led_pins[0]);

// 初始化 LED 和 SysTick
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/systick.h>
#include "non_blocking_led.h"

// 定义 LED 端口
#define LED_PORT GPIOA

// 定义 LED 引脚数组
const uint16_t led_pins[] = {GPIO5, GPIO6, GPIO7};
const uint8_t num_leds = sizeof(led_pins) / sizeof(led_pins[0]);

// 初始化 LED 和 SysTick
void led_init(LedState *led, uint32_t interval) {
    // 使能 GPIOA 时钟
    rcc_periph_clock_enable(RCC_GPIOA);

    // 配置 LED 引脚为推挽输出
    for (int i = 0; i < num_leds; i++) {
        gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, led_pins[i]);
    }

    // 初始化 SysTick
    systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
    uint32_t reload_value = rcc_ahb_frequency / 1000;
    systick_set_reload(reload_value); // 1ms 中断一次
    systick_interrupt_enable();
    systick_counter_enable();

    // 初始化 LED 状态
    led->last_toggle_time = 0;
    led->toggle_interval = interval;
    led->current_led = 0;

    // 初始时关闭所有 LED
    for (int i = 0; i < num_leds; i++) {
        gpio_clear(LED_PORT, led_pins[i]);
    }
}

// 非阻塞更新 LED 状态
void led_update(LedState *led) {
    uint32_t current_time = systick_get_value();
    uint32_t elapsed_time;

    if (current_time <= led->last_toggle_time) {
        // 处理计数器溢出的情况
        elapsed_time = led->last_toggle_time - current_time;
    } else {
        // 正常情况
        elapsed_time = (UINT32_MAX - current_time) + led->last_toggle_time + 1;
    }

    printf("Current time: %lu\n", current_time);
    printf("Last toggle time: %lu\n", led->last_toggle_time);
    printf("Elapsed time: %lu\n", elapsed_time);

    if (elapsed_time >= led->toggle_interval) {
        led->last_toggle_time = current_time;

        // 关闭当前点亮的 LED
        gpio_clear(LED_PORT, led_pins[led->current_led]);

        // 切换到下一个 LED
        led->current_led = (led->current_led + 1) % num_leds;

        // 点亮新的 LED
        gpio_set(LED_PORT, led_pins[led->current_led]);
    }
}